From 00a64f672abc194a00436364d24a14c1e1becd93 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 23 Jul 2004 15:50:54 +0000 Subject: [PATCH] bitkeeper revision 1.1108.2.24 (410133delTf8MZfF-gDO2KEJpDxCOg) Ensure that merged scatter-gather lists are valid in the face of moulinexed machine address space. --- linux-2.4.26-xen-sparse/include/asm-xen/pci.h | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/linux-2.4.26-xen-sparse/include/asm-xen/pci.h b/linux-2.4.26-xen-sparse/include/asm-xen/pci.h index 74ae5ba8b1..382b7a41de 100644 --- a/linux-2.4.26-xen-sparse/include/asm-xen/pci.h +++ b/linux-2.4.26-xen-sparse/include/asm-xen/pci.h @@ -145,7 +145,8 @@ static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { - int i; + int i, j, nr_pfns; + unsigned long first_pfn; if (direction == PCI_DMA_NONE) out_of_line_bug(); @@ -159,10 +160,28 @@ static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, else if (!sg[i].address && !sg[i].page) out_of_line_bug(); - if (sg[i].address) + if (sg[i].address) { sg[i].dma_address = virt_to_bus(sg[i].address); - else + first_pfn = virt_to_phys(sg[i].address) >> PAGE_SHIFT; + nr_pfns = (((unsigned long)sg[i].address & + (PAGE_SIZE-1)) + sg[i].length + PAGE_SIZE - 1) >> + PAGE_SHIFT; + } else { sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; + first_pfn = page_to_phys(sg[i].page) >> PAGE_SHIFT; + nr_pfns = (sg[i].offset + sg[i].length + PAGE_SIZE - + 1) >> PAGE_SHIFT; + } + + /* + * Check that we merged physical buffers are also contiguous + * in machine-address space. We try to fail by returning 0. + */ + for (j = 1; j < nr_pfns; j++) { + if ( unlikely(pfn_to_mfn(first_pfn+j) != + (pfn_to_mfn(first_pfn)+j)) ) + return 0; + } } flush_write_buffers(); -- 2.30.2